﻿using System;
using System.Collections.Generic;
using System.Text;

namespace GenericityStudy
{
    //泛型约束的学习  https://www.cnblogs.com/jara/p/3458583.html  继承泛型类和接口
    struct a { };
    class obe { 
        
    }

    class chi : obe { 
    
    }

    //T,U泛型约束为值类型
    class Btest1<T, U> where T : class,new() where U : struct {
        //泛型方法中参数泛型约束为引用类型
        public void Test1<K>(T t) where K : class,new() {
            Console.WriteLine(t);
        } 

    }

    class Btest2<T, U> where T : obe, new() where U : struct
    {
        //泛型方法中参数泛型约束为引用类型
        public void Test1<K>(T t) where K : chi, new()
        {
            Console.WriteLine(t);
        }

    }

    class Base1Child<Y> : Btest1<obe, int>
    { 

    }

    


    public interface Ibase<T, U>  {
        public void Iset(T t, U u);
    }

    class ChildIbase<T,U>:Ibase<T, U> where T : struct where U:class
    {
        public void Iset(T t, U u) { 
            
        }
    }

    public interface IList<T>
    {
        T[] GetElements();
    }
    public interface IDictionary<K, V>
    {
        void Add(K key, V value);
    }

    // 泛型接口的类型参数要么已实例化  
    // 要么来源于实现类声明的类型参数  
    class List<T> : IList<T>, IDictionary<int, T>
    {
        public T[] GetElements() { return null; }
        public void Add(int index, T value)
        { }
    }

    public class Test<T, S> {
        
    }
    public class TestChild : Test<string, int> { }
    public class TestChild1<T, S> : Test<T, S> { }
    public class TestChild2<T, S> : Test<String, int> { }

    class GenericityLimit
    {
        static void Main() {
            Btest1<obe, a> base1 = new Btest1<obe, a>();
            a a1;
            int a2=666;
            base1.Test1<object>(new chi());
            Console.WriteLine("=================");


            Btest2<obe, int> base2 = new Btest2<obe, int>();
            base2.Test1<chi>(new chi());
            base2.Test1<chi>(new obe());
            Btest2<chi, int> base3 = new Btest2<chi, int>();
            //注意如果指定了泛型类的数据类型，那么类中使用到该泛型的泛型函数都只能用其本身和子类
            base3.Test1<chi>(new chi());

            Console.WriteLine("=================");
        }

    }
}
